/**
 * Xy Common Tools.
 */
class XyTools {

  constructor() {

  }

  /**
   * FormatDate 格式化日期
   * @param {*} date 日期
   * @param {*} format 格式化类型 
   * @param {*} symbol_date 日期符号
   * @param {*} symbol_time 时间符号 
   * @param {*} type 12 | 24
   * @returns 
   */
  FD(date: Date, format = 0, symbol_date = '-', symbol_time = ':', type = 24) {

    var D = new Date(date);

    type == 12 ? 12 : 24; // 24 小时格式

    var y = D.getFullYear();

    var m = (D.getMonth() + 1).toString().padStart(2, '0'); // 	不及 2 位的用 0 补齐

    var d = D.getDate().toString().padStart(2, '0');

    var noon; // 记录上午 下午

    if (type == 12) {
      var arr = D.toLocaleTimeString('chinese', { hour12: true }).split('');

      noon = arr[0] + arr[1];

      arr.splice(0, 2);

      arr = arr.join('').split(':');

      var h = arr[0];

      var min = arr[1];

      var s = arr[2];
    } else {
      var h = D.getHours().toString().padStart(2, '0');

      var min = D.getMinutes().toString().padStart(2, '0');

      var s = D.getSeconds().toString().padStart(2, '0');
    }

    if (symbol_date && symbol_time) { // 以符号拼接
      if (format == 0) {
        return [y, m, d].join(symbol_date.toString()) + ' ' + [h, min, s].join(symbol_time) + (type == 12 ? (' ' + noon) : '');
      } else if (format == 1) {
        return [y, m, d].join(symbol_date.toString());
      } else {
        return [h, min, s].join(symbol_time) + (type == 12 ? (' ' + noon) : '');;
      }
    } else if (symbol_date && !symbol_time) {
      if (format == 0) {
        return [y, m, d].join(symbol_date.toString()) + ' ' + h + '时' + min + '分' + s + '秒' + (type == 12 ? (' ' + noon) : '');
      } else if (format == 1) {
        return [y, m, d].join(symbol_date.toString());
      } else {
        return h + '时' + min + '分' + s + '秒' + (type == 12 ? (' ' + noon) : '');
      }
    } else if (!symbol_date && symbol_time) {
      if (format == 0) {
        return y + '年' + m + '月' + d + '日' + ' ' + [h, min, s].join(symbol_time) + (type == 12 ? (' ' + noon) : '');
      } else if (format == 1) {
        return y + '年' + m + '月' + d + '日';
      } else {
        return [h, min, s].join(symbol_time) + (type == 12 ? (' ' + noon) : '');
      }
    } else {
      if (format == 0) {
        return y + '年' + m + '月' + d + '日' + ' ' + h + '时' + min + '分' + s + '秒' + (type == 12 ? (' ' + noon) : '');
      } else if (format == 1) {
        return y + '年' + m + '月' + d + '日';
      } else {
        return h + '时' + min + '分' + s + '秒' + (type == 12 ? (' ' + noon) : '');
      }
    }
  }

  /**
   * CNDateString 将日期转化为大写
   * @param {*} date 
   * @returns 
   */
  CS(date: Date) {
    var cn: string[] = ["〇", "一", "二", "三", "四", "五", "六", "七", "八", "九"];
    var s = [];
    var YY: string = date.getFullYear().toString();
    for (var i: number = 0; i < YY.length; i++)
      if (cn[YY.charAt(i) as any])
        s.push(cn[YY.charAt(i) as any]);
      else
        s.push(YY.charAt(i));
    s.push("年");
    var MM = date.getMonth() + 1;
    if (MM < 10)
      s.push(cn[MM]);
    else if (MM < 20)
      s.push("十" + cn[MM % 10]);
    s.push("月");
    var DD = date.getDate();
    if (DD < 10)
      s.push(cn[DD]);
    else if (DD < 20)
      s.push("十" + cn[DD % 10]);
    else
      s.push("二十" + cn[DD % 10]);
    s.push("日");

    return s.join('');
  }

  /**
   * 设置 LocalStorage sessionStorage
   * @param {*} key 
   * @param {*} data 
   * @param {*} mode 
   */
  set(key: string, data: any, mode = 1) {
    try {
      const result = JSON.stringify(data)

      if (mode) {
        localStorage.setItem(key, result)
      } else {
        sessionStorage.setItem(key, result)
      }
    } catch (error) {
      if (mode) {
        localStorage.setItem(key, data)
      } else {
        sessionStorage.setItem(key, data)
      }
    }
  }

  /**
   * 获取 LocalStorage sessionStorage
   * @param {*} key 
   * @param {*} mode 
   * @returns 
   */
  get(key: string, mode = 1) {
    let data: any;

    if (mode) {
      data = localStorage.getItem(key)
    } else {
      data = sessionStorage.getItem(key)
    }

    try {
      const result = JSON.parse(data)
      return result
    } catch (error) {
      return data
    }
  }

  /**
   * 移除 LocalStorage sessionStorage
   * @param {*} key 
   * @param {*} mode 
   * @returns 
   */
  remove(key: string, mode = 1) {
    try {
      if (mode) {
        localStorage.removeItem(key)
      } else {
        sessionStorage.removeItem(key)
      }

      return true
    } catch (error) {
      return false
    }
  }

  /**
   * 将base64转换为文件对象
   * @param {*} dataurl 
   * @param {*} filename 
   * @param {*} type 
   * @returns 
   */
  DUF(dataurl: string, filename: string, type = 'file') {
    var arr = dataurl.split(',');

    var mime = arr[0].match(/:(.*?);/)![1];

    var bstr = atob(arr[1]);
    var n = bstr.length
    var u8arr = new Uint8Array(n);
    while (n--) {
      u8arr[n] = bstr.charCodeAt(n);
    }

    if (type == 'blob') {
      //! 转换成成blob对象
      return new Blob([u8arr], { type: mime });
    } else {
      //! 转换成file对象
      return new File([u8arr], filename, {
        type: mime
      });
    }
  }

  /**
   * searchReslove 解析search参数
   * @returns 
   */
  SR() {
    let search = location.search.substring(1);

    let _obj = {};

    /* 尾部存在 '/' 的时候去除 */
    if (search[search.length - 1] === '/') {
      search = search.substring(0, search.length - 1);
    }

    search.split('&').forEach((item) => {
      _obj = { ..._obj, ...Object.fromEntries([item.split('=')]) }
    });

    return _obj;
  }

  /**
   * 打印
   * @param  {...any} arg 
   */
  log(...arg: any[]) {
    let css = 'background-color: #527ce8; padding: 1px 6px;border-radius: 5px; color: #fff';

    let title = 'xy';

    if (String(arg[0]).charAt(0) === '~') {
      title = arg[0].substring(1);
      arg.shift();
    }

    console.log('%c%s', css, title, ...arg);
  }

  /**
   * 警告
   * @param  {...any} arg 
   */
  warn(...arg: any[]) {
    let css = 'background-color: #f80; padding: 1px 6px;border-radius: 5px; color: #fff';

    let title = 'xy';

    if (String(arg[0]).charAt(0) === '~') {
      title = arg[0].substring(1);
      arg.shift();
    }

    console.warn('%c%s', css, title, ...arg);
  }

  /**
   * 错误
   * @param  {...any} arg 
   */
  error(...arg: any[]) {
    let css = 'background-color: #f00; padding: 1px 6px;border-radius: 5px; color: #fff';

    let title = 'xy';

    if (String(arg[0]).charAt(0) === '~') {
      title = arg[0].substring(1);
      arg.shift();
    }

    console.error('%c%s', css, title, ...arg);
  }

  /**
   * 随机数
   * @param {*} length 长度
   * @returns 
   */
  RI(length = 8) {
    let ID: any = '';

    while (ID.length < 32) {
      ID = ID + Number(Math.random().toString().substring(3, 5) + Date.now()).toString(36);
    }

    ID = ID.split('');

    ID.map((item: any, index: number) => {
      let flag = Math.round(Math.random());

      if (flag) {
        //! 随机转化为大写
        ID[index] = item.toUpperCase();
      }
    });

    return ID.slice(0, length < 32 ? length : 32).join('');
  }

  /**
   * zipImg 图片压缩
   * @param {*} file 
   * @param {*} maxSize 
   * @param {*} quality 
   */
  ZI(file: any, maxSize: number, quality: number) {
    if (file.file.size > maxSize) {
      // 创建Canvas对象(画布)
      var canvas = document.createElement('canvas');
      // 获取对应的CanvasRenderingContext2D对象(画笔)
      var context = canvas.getContext('2d');
      // 创建新的图片对象
      var img = new Image();
      // 指定图片的DataURL(图片的base64编码数据)
      img.src = file.content;

      img.onload = () => {
        // 监听浏览器加载图片完成，然后进行进行绘制
        // 指定canvas画布大小，该大小为最后生成图片的大小
        if (file.file.name.split('.')[1] == 'png') {
          canvas.width = 1600;
          canvas.height = 900;
        } else {
          canvas.width = 2560;
          canvas.height = 1440;
        }

        /* drawImage画布绘制的方法。(0,0)表示以Canvas画布左上角为起点，400，300是将图片按给定的像素进行缩小。
              如果不指定缩小的像素图片将以图片原始大小进行绘制，图片像素如果大于画布将会从左上角开始按画布大小部分绘制图片，最后的图片就是张局部图。*/
        context!.drawImage(img, 0, 0, canvas.width, canvas.height);
        // 将绘制完成的图片重新转化为base64编码，file.file.type为图片类型，0.92为默认压缩质量
        var base_img = canvas.toDataURL(file.file.type, quality);

        var blodBin = atob(base_img.split(',')[1]);
        var data = [];
        for (var i = 0; i < blodBin.length; i++) {
          data.push(blodBin.charCodeAt(i));
        }
        var blob1 = new Blob([new Uint8Array(data)], { type: 'image/png' });
        var file1 = new File([blob1], new Date().getTime() + '.png');

        return file1;
      };
    }
  }

  /**
   * 格式化金额
   * @param {*} money 
   * @param {*} symbol 
   * @returns 
   */
  FM(money: number, symbol: string) {

    symbol = symbol || '￥' // 默认是RMB

    let str = Number(money).toFixed(2)  // 只取2位小数

    let l = str.split('.')[0] // 获取整数位

    let r = str.split('.')[1] // 获取小数位

    let arr = [] // 用于保存结果

    let len = Math.ceil(l.length / 3) // 3位数一个 `,`

    for (let i = 0; i < len; i++) {

      arr.unshift(l.slice(-3 * (i + 1), -3 * i || undefined)) // 如果传(-3,0)获取不到参数，将0换成undefined相当于没传

      if (i !== len - 1) { // 最后一次截取不加 `,`了
        arr.unshift(',')
      }
    }

    return symbol + arr.join('') + '.' + r
  }

  /**
   * debounce 防抖
   * @param {*} fn 
   * @param {*} delay 
   * @returns 
   */
  DB(fn: Function, delay: number) {
    let t: any = null
    return () => {
      if (t !== null) {
        clearTimeout(t)
      }
      t = setTimeout(() => {
        fn.call(this)
      }, delay)
    }
  }

  /**
   * throttle 节流
   * @param {*} fn 
   * @param {*} delay 
   * @returns 
   */
  TT(fn: Function, delay: number) {
    let flag = true;
    return () => {
      if (flag) {
        setTimeout(() => {
          fn.call(this)
          flag = true
        }, delay)
      }
      flag = false
    }
  }

  /**
   * pauseEvent 清除默认事件 事件冒泡
   * @param {*} e 
   * @returns 
   */
  PE(e: Event) {
    e = e || window.event;

    if (e.stopPropagation) e.stopPropagation(); //清除冒泡

    if (e.preventDefault) e.preventDefault(); // 移除默认事件

    e.cancelBubble = true; // 兼容火狐的冒泡

    e.returnValue = false;

    return false;
  }

  /**
   * isNullString 去空格
   * @param {*} val 
   * @returns 
   */
  IS(val: string) {
    return (val == '' || val.trim() == '');
  }
}

export default XyTools;

